#include <iostream>

#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

#include <fstream>
#include <iostream>
#include <string.h>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
#include "api/datatype.hpp"
#include <algorithm>
#include "api/graphwalker_basic_includes.hpp"


std::vector<vid_t> get_newfile(std::string ver2part_file,std::string original_file,std::string new_file,bid_t part_num ){
    std::unordered_map<vid_t,vid_t>  verttovert;
    std::vector<std::vector<bid_t>> vec(part_num);
    std::vector<std::pair<vid_t, vid_t>> pair_vec;
    std::vector<vid_t> return_vec; 

    FILE * inf = fopen(ver2part_file.c_str(), "r");
    char s[1024];
    vid_t temp;
    vid_t count = 0;
    while(fgets(s, 1024, inf) != NULL) {
        char *t1;
        t1 = strtok(s, "\n"); 
        temp = atoi(t1);
        vec[temp].push_back(count);
        count++;
    }
    
    fclose(inf);
    count=0;
    for(auto &a:vec){
        return_vec.push_back(a.size());
        for(auto &b:a){
            verttovert.emplace(b, count);//原先id->当前id
            count++;
        }
    }
    
    inf=fopen(original_file.c_str(), "r");
    while(fgets(s, 1024, inf) != NULL) {
        if (s[0] == '#') continue; // Comment
        if (s[0] == '%') continue; // Comment
        char *t1, *t2;
        t1 = strtok(s, "\t, ");
        t2 = strtok(NULL, "\t, ");
        if (t1 == NULL || t2 == NULL ) {
            logstream(LOG_ERROR) << "Input file is not in right format. "
            << "Expecting <from> <to>. "
            << "Current line: " << s << "\n";
            assert(false);
        }
        pair_vec.push_back(std::pair<vid_t, vid_t>(verttovert[atoi(t1)],verttovert[atoi(t2)]));
    }
    fclose(inf);
    std::sort(pair_vec.begin(), pair_vec.end());
    std::ofstream file(new_file);
    assert(file.is_open());
    for (const auto& p : pair_vec) {
        file<<p.first<<" "<<p.second<<std::endl;
    }
    file.close();
    verttovert.clear();
    vec.clear();
    pair_vec.clear();

    return return_vec;
}
int main(int argc, const char ** argv){
    set_argc(argc,argv);
    std::string original_file = get_option_string("file", "./dataset/karate.edgelist");
    std::string partition_mode = get_option_string("par_mode", "naive");
    bid_t p_num = get_option_int("p_num", 3);

    std::string ver2part_file = original_file + "_" + partition_mode + "_" + std::to_string(p_num) + ".ver2part";
    logstream(LOG_INFO) << "ver2part_file: " << ver2part_file << std::endl;
    std::string new_file = original_file + "_" + partition_mode + "_" + std::to_string(p_num) + "_new";
    
    // unsigned long long blocksize_kb = get_option_long("blocksize_kb", 1024); // Size of block, represented in KB
    std::vector<vid_t> a = get_newfile(ver2part_file, original_file, new_file, p_num); // 每个分区中的顶点个数
    vid_t presum = 0;
    for(auto &x:a){
        x = presum + x;
        presum = x;
    } 
    bid_t nblocks = convert_if_notexists(new_file, p_num);
    assert(nblocks == p_num);
    //修改block划分
    std::string blockrangefile = blockrangename(new_file, p_num);
    std::ofstream brf(blockrangefile.c_str(), std::ios::trunc); 
    brf << 0 << std::endl;
    for(auto &x:a){
        brf << x << std::endl; 
    }
    brf.close();
}